import * as THREE from 'three';
import { SceneUtils } from 'three/examples/jsm/utils/SceneUtils';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

export function init04(width, height) {
  // 创建一个场景，它将包含我们所有的元素，如对象，相机和灯光。
  const scene = new THREE.Scene();

  // 创建一个摄像机，它定义了我们正在查看的位置。
  const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);

  // 创建一个渲染器和设置大小
  const renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(width, height);
  renderer.shadowMap.enabled = true;

  // 创建平面
  const planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
  const planeMaterial = new THREE.MeshLambertMaterial({
    color: 0xffffff
  });
  const plane = new THREE.Mesh(planeGeometry, planeMaterial);

  // 旋转并定位平面
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;
  // 接收阴影
  plane.receiveShadow = true;
  // 将平面添加到场景中
  scene.add(plane);

  // 将相机定位并指向场景的中心
  camera.position.set(-30, 40, 30);
  camera.lookAt(scene.position);

  // 添加光源
  const ambientLight = new THREE.AmbientLight(0x3c3c3c);
  scene.add(ambientLight);

  // 为阴影添加聚光灯
  const spotLight = new THREE.SpotLight(0xffffff, 1.2, 150, 120);
  spotLight.position.set(-40, 60, -10);
  spotLight.castShadow = true;
  scene.add(spotLight);

  // 添加几体图形
  addGeometries(scene);

  // 视角操作
  const orbit = new OrbitControls(camera, renderer.domElement);

  // 将呈现器的输出添加到html元素中
  document.getElementById('webgl-output').appendChild(renderer.domElement);

  // 浏览器大小自适应
  window.addEventListener('resize', onResize, false);

  render();

  function addGeometries(scene) {
    // 几何体数组
    const geometries = [];
    // 圆柱体
    geometries.push(new THREE.CylinderGeometry(1, 4, 4));
    // 方体
    geometries.push(new THREE.BoxGeometry(2, 2, 2));
    // 球体
    geometries.push(new THREE.SphereGeometry(2));
    // 二十面体;
    geometries.push(new THREE.IcosahedronGeometry(4));
    // 八面体
    geometries.push(new THREE.OctahedronGeometry(3));
    // 四面体
    geometries.push(new THREE.TetrahedronGeometry(3));
    // 环体
    geometries.push(new THREE.TorusGeometry(3, 1, 10, 10));
    // 环形结体
    geometries.push(new THREE.TorusKnotGeometry(3, 0.5, 50, 20));
    // 迭代几何体
    let j = 0;
    geometries.forEach((_, index) => {
      const materials = [
        new THREE.MeshLambertMaterial({
          color: Math.random() * 0xffffff
        }),
        new THREE.MeshBasicMaterial({
          color: 0x000000,
          wireframe: true
        })
      ];
      const mesh = new SceneUtils.createMultiMaterialObject(
        geometries[index],
        materials
      );
      mesh.traverse(e => {
        e.castShadow = true;
      });
      mesh.position.x = -24 + (index % 4) * 12;
      mesh.position.y = 4;
      mesh.position.z = -8 + j * 12;
      if ((index + 1) % 4 == 0) {
        j++;
      }
      scene.add(mesh);
    });
  }

  function render() {
    orbit.update();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }

  function onResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(width, height);
  }
}
